﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MdflCommonUtils {
    public class ObjectUtil {
        /// <summary>
        /// 转换为对应类型
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="o"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T To<T>(object o, T defaultValue) {
            if (o == null || o == DBNull.Value || "".Equals(o)) {
                return defaultValue;
            }
            if (o is T t) {
                return t;
            }
            Type type = typeof(T);
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {
                if (o == null || o == DBNull.Value) {
                    return defaultValue;
                }
                type = Nullable.GetUnderlyingType(type);
            }
            return (T)Convert.ChangeType(o, type);
        }

        /// <summary>
        /// 转换为对应类型
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static T To<T>(object o) {
            return To<T>(o, default);
        }

        /// <summary>
        /// 模仿数据库 decode函数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static T Decode<T>(object o, params object[] args) {
            if (args.Length < 2) {
                throw new ArgumentException("args 的长度必须大于等于2");
            }
            object ret = null;

            for (int i = 0; ;) {
                if (i >= args.Length) {
                    break;
                }
                object argObj = args[i];
                if (i == args.Length - 1) {
                    ret = argObj;
                    break;
                }
                if (o == null && argObj == null || o == DBNull.Value && argObj == null
                    || o == null && argObj == DBNull.Value || o != null && o.Equals(argObj)) {

                    ret = args[i + 1];
                    break;
                }
                i += 2;
            }
            if (ret == null || ret == DBNull.Value) {
                return default;
            }
            return (T)Convert.ChangeType(ret, typeof(T));
        }

        /// <summary>
        /// 模仿数据库 NVL函数
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="o"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T Nvl<T>(object o, T defaultValue) {
            if (o == null || o == DBNull.Value || "".Equals(o)) {
                return defaultValue;
            }
            if (o is T t1) {
                return t1;
            }
            Type t = typeof(T);
            if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
                if (o == null || o == DBNull.Value) {
                    return defaultValue;
                }
                t = Nullable.GetUnderlyingType(t);
            }
            return (T)Convert.ChangeType(o, t);
        }

        /// <summary>
        /// 模仿数据库 NVL函数
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static T Nvl<T>(object o) {
            return Nvl<T>(o, default);
        }
    }
}
